/**
 * 
 */
package fachkonzept;

import util.Car;
import util.Colour;
import util.EngineType;
import datenhaltung.IDatenhaltung;

/**
 * @author Sebastian
 * refreshs the current result in a specified intervall
 * after searching cars by specific parameters
 */
class RefreshingCarSearcher implements ICarSearcher, Runnable{
	
	CarResult result;
	IDatenhaltung dataSource;
	long refreshInterval;
	Car lastSearchPatternCar;
	Thread refresher;
	/**
	 * create a new <code>RefreshingCarSearcher</code>
	 */	
	RefreshingCarSearcher(){
		
		this.result = new CarResult();
		this.refresher = new Thread(this);
	}
	/**
	 * create a new <code>RefreshingCarSearcher</code>
	 * @param dataSource the data source to use
	 * @param refreshInterval the interval in milliseconds whereupon the result will be refreshed
	 */	
	RefreshingCarSearcher(IDatenhaltung dataSource, long refreshInterval){
		
		this();
		this.dataSource = dataSource;
		this.refreshInterval = refreshInterval;
		startRefreshingLoop();
	}
	/**
	 * @return the result
	 */
	CarResult getResult() {
		return result;
	}
	/**
	 * @param result the result to set
	 */
	void setResult(CarResult result) {
		this.result = result;
	}
	/**
	 * @return the dataSource
	 */
	IDatenhaltung getDataSource() {
		return dataSource;
	}
	/**
	 * @param dataSource the dataSource to set
	 */
	void setDataSource(IDatenhaltung dataSource) {
		this.dataSource = dataSource;
	}
	/**
	 * @return the refreshInterval
	 */
	long getRefreshInterval() {
		return refreshInterval;
	}
	/**
	 * @param refreshInterval the refreshInterval to set
	 */
	void setRefreshInterval(long refreshInterval) {
		this.refreshInterval = refreshInterval;
	}
	/**
	 * @return the lastSearchPatternCar
	 */
	Car getLastSearchPatternCar() {
		return lastSearchPatternCar;
	}
	/**
	 * @param lastSearchPatternCar the lastSearchPatternCar to set
	 */
	void setLastSearchPatternCar(Car lastSearchPatternCar) {
		this.lastSearchPatternCar = lastSearchPatternCar;
	}
	/**
	 * @return the refresher
	 */
	Thread getRefresher() {
		return refresher;
	}
	/**
	 * @param refresher the refresher to set
	 */
	void setRefresher(Thread refresher) {
		this.refresher = refresher;
	}
	/**
	 * saves car with parameters
	 * and determines by the identification to create a new one or to update an existing one
	 * @param identificationNumber the identification number to save
	 * @param theColour colour to save
	 * @param theEngineType engine type save
	 * @param yearOfConstruction year of construction to save
	 * @param originPrice origin price to save
	 * @param price the price to save
	 * @param mileage the mileage to save
	 * @param isSelled the selling state to save
	 * @return String[] of matching cars' identification numbers
	 */
	@Override
	public synchronized void search(String identificationNumber, Colour theColour,
			EngineType theEngineType, int yearOfConstruction, double originPrice,
			double price, int mileage, boolean isSelled, String carType, String manufacturer, String model) {
		
		createSearchPatternCar(identificationNumber, theColour, theEngineType, yearOfConstruction, originPrice, price, mileage, isSelled, carType, manufacturer, model );
		searchCurrentPattern();
		
	}
	/**
	 * deletes Car with matching identification number
	 * @param cars' identification number
	 */
	@Override
	public Car getCar(String identificationNumber) {

		return result.get(identificationNumber);
	}
	/**
	 * returns the identification numbers of all cars in the current result
	 * @return all identification numbers of the current result
	 */
	@Override
	public String[] getIdentificationNumbers() {
		
		Object[] theKeysAsObjects = result.keySet().toArray();
		String[] identificationNumbers = new String[theKeysAsObjects.length];
		for( int i=0; i < theKeysAsObjects.length; i++){
			
			identificationNumbers[i] = (String)theKeysAsObjects[i];
		}
		return identificationNumbers;
	}
	/**
	 * refreshes the current result with the current pattern
	 * stored while the last search
	 */
	private synchronized void searchCurrentPattern(){
		
		Car[] foundCars = dataSource.getCars(this.lastSearchPatternCar);
		result.fill(foundCars);
	}
	/**
	 * creates a car as a search pattern for the data source
	 * @param identificationNumber the identification number
	 * @param theColour colour to search for
	 * @param theEngineType engine type to search for
	 * @param yearOfConstruction year of construction to search for
	 * @param originPrice origin price to search for
	 * @param price the price to search for
	 * @param mileage the mileage to search for
	 * @param isSelled the selling state to search for
	 */
	private void createSearchPatternCar(String identificationNumber, Colour theColour,
			EngineType theEngineType, int yearOfConstruction, double originPrice,
			double price, int mileage, boolean isSelled,String carType, String manufacturer, String model){
		
		this.lastSearchPatternCar = new Car(
				identificationNumber,
				theColour, 
				theEngineType, 
				yearOfConstruction, 
				originPrice, 
				price, 
				mileage, 
				isSelled,
				carType,
				manufacturer,
				model);
	}
	/**
	 * starts a new thread for refreshing the result for one time
	 */
	public void startRefreshingLoop(){
		
		refresher.start();
	}
	/**
	 * the refreshing loop for the result
	 * is called by another thread
	 */
	@Override
	public void run() {
		while(this.lastSearchPatternCar == null){
			try {
				Thread.sleep(refreshInterval);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		while(true){
			
			searchCurrentPattern();
			
			try {
				Thread.sleep(refreshInterval);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	
	}
}
